package ${webPackageName}.aspect;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSONObject;
import ${commonPackageName}.annotation.Permission;
import ${commonPackageName}.constant.Constant;
import ${commonPackageName}.enums.ExceptionEnum;
import ${commonPackageName}.exception.BusinessException;
import ${commonPackageName}.utils.AssertUtil;
import ${commonPackageName}.utils.RedisUtil;
import ${servicePackageName}.dto.sys.UserDto;
import ${webPackageName}.constant.ScanPackageConstant;
import ${webPackageName}.utils.RequestHolder;

import cn.hutool.core.util.StrUtil;

/**
 * 
 * @author lizihao
 *
 */
@Component
@Aspect
@Order(2)
<#noparse>
public class PermissionAspect {
    @Resource
    private RedisUtil redisUtil;

	@Pointcut(ScanPackageConstant.PERMISSION_POINTCUT)
    public void permission() {
    }

	@Before("permission()")
	public void toLogin(JoinPoint pjp) throws Throwable {
		//获取request和response
	 	ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("Authorization");
        Object redisObject = redisUtil.get(token);
        AssertUtil.isNull(redisObject, () -> new BusinessException(ExceptionEnum.TOKENGUOQI));
        UserDto loginDto =JSONObject.parseObject(redisObject.toString(), UserDto.class);
        //重新刷新token失效时间
        redisUtil.expire(token, Constant.TOKEN_TIME_OUT);
        //放到requestHolder以便可以直接获取用户信息
        RequestHolder.add(loginDto);
        //去redis查询该用户的权限列表
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Permission annotation = signature.getMethod().getAnnotation(Permission.class);
        String p = annotation.permission();
        if(!StrUtil.isBlank(p)) {
        	//需要验证登录和权限
        	AssertUtil.isTrue(loginDto.getPermissionList().size()==0, () -> new BusinessException(ExceptionEnum.NOT_ENOUGTH_PERMISSION));
        	AssertUtil.isTrue(!loginDto.getPermissionList().contains(p), () -> new BusinessException(ExceptionEnum.NOT_PERMISSION));
        }
	  }
	
	@After("permission()")
    public void after() {
        RequestHolder.remove();
    }
	
}
</#noparse>